public class SearchCatalogForOpportunityCtlr{
    // Opportunity record
    public final Opportunity opportunityRec;
    // Constructor
    public SearchCatalogForOpportunityCtlr(ApexPages.StandardController stdCon){
        system.debug('====SearchCatalogForOpportunityCtlr constructor');
        this.opportunityRec = (Opportunity)stdCon.getRecord();
        opportunityRecordTypeId = ((String)opportunityRec.RecordTypeId).subString(0, 15);
        List<Opportunity> listOpportunity = [Select Campus__c, Program__c, Payment_plan__c From Opportunity Where Id = :this.opportunityRec.Id];
        system.debug('====Opportunity size: ' + listOpportunity.size());
        if (listOpportunity.size() > 0){
            strCampusId = listOpportunity[0].Campus__c;
            strProgramId = listOpportunity[0].Program__c;
            paymentOptions = mapPaymentOptionsValue.get(listOpportunity[0].Payment_plan__c);
            if (paymentOptions == null){
                paymentOptions = '';
            }
            if (opportunityRecordTypeId != null && opportunityRecordTypeId != ''){
                //catalogRecordTypeName = mapOpportunityToCatalogRecordType.get(opportunityRecordTypeId);
                catalogRecordTypeName = mapOpportunityToCatalogRecordType.get(mapOpportunityRecordTypes.get(opportunityRecordTypeId.subString(0, 15)));
                system.debug('====Catalog recordType Id: ' + catalogRecordTypeName);
                if (strCampusId != null && strCampusId != '' && strProgramId != null && strProgramId != ''){
                    Integer nCount = [Select Count() From Catalog__c Where Campus__c = :strCampusId AND 
                                        Program__c = :strProgramId AND 
                                        //recordTypeId = :catalogRecordTypeName AND 
                                        recordType.DeveloperName = :catalogRecordTypeName AND 
                                        Active__c = true];
                    if (nCount == 0){
                        strProgramId = '';
                        strCampusId = '';
                    }
                }
            }
        }
        bClosePage = false;
    }
    
    // Error flag to stop closing the submit
    public static Boolean bClosePage{ get; set; }
    
    // Display payment plan
    public Boolean DisplayPaymentPlan{
        get{
            DisplayPaymentPlan = true;
            List<OpportunityToCatalogRecordTypes__c> listCS = OpportunityToCatalogRecordTypes__c.getAll().values();
            for (OpportunityToCatalogRecordTypes__c cs : listCS){
                //if (cs.OpportunityRecordType__c == OpportunityRecordTypeId){
                if (cs.OpportunityRecordType__c == mapOpportunityRecordTypes.get(OpportunityRecordTypeId)){
                    DisplayPaymentPlan = cs.Display_Payment_Plan__c;
                    break;
                }
            }
            return DisplayPaymentPlan;
        }
        set;
    }
            
    
    // Record Id Parameter from Opportunity detail page
    public String opportunityRecordTypeId{ get; set; }
    public String opportunityRecordTypeName{ get; set; }
    public String catalogRecordTypeName { get; set; }
    
    // Map of Opportunity record types to Catalog record Types
    public Map<String, String> mapOpportunityToCatalogRecordType{
        get{
            if (mapOpportunityToCatalogRecordType == null){
                mapOpportunityToCatalogRecordType = new Map<String, String>();
                List<OpportunityToCatalogRecordTypes__c> listCS = OpportunityToCatalogRecordTypes__c.getAll().values();
                System.debug('====Custom Settings size: ' + listCS.size());
                for(Integer nCount = 0; nCount < listCS.size(); nCount++){
                    System.debug('====OpportunityRecordType: ' + listCS[nCount].OpportunityRecordType__c);
                    system.debug('====CatalogRecordType: ' + listCS[nCount].CatalogRecordType__c);
                    mapOpportunityToCatalogRecordType.put(listCS[nCount].OpportunityRecordType__c, listCS[nCount].CatalogRecordType__c);
                }
            }
            return mapOpportunityToCatalogRecordType;
        }
        set;
    }
    
    // Map of Opportunity record type ids to record type name
    public Map<String, String> mapOpportunityRecordTypes{
        get{
            if (mapOpportunityRecordTypes == null){
                mapOpportunityRecordTypes = new Map<String, String>();
                /*List<Schema.RecordTypeInfo> listRecTypes = Opportunity.sObjectType.getDescribe().getRecordTypeInfos();
                for (Schema.RecordTypeInfo rti : listRecTypes){
                    system.debug('====Opp Rec Type: ' + rti.getName());
                    mapOpportunityRecordTypes.put(rti.getRecordTypeId(), rti.getName());
                }*/
                for(List<RecordType> listRecType : [Select Id, DeveloperName From RecordType Where SObjectType = 'Opportunity']){
                    for(RecordType rt : listRecType){
                        System.debug('====Opp Rec Type: ' + rt.DeveloperName);
                        String strId = rt.Id;
                        mapOpportunityRecordTypes.put(strId.subString(0, 15), rt.DeveloperName);
                    }
                }
            }
            return mapOpportunityRecordTypes;
        }
        set;
    }
    
    // Campus selected by user
    public String strCampusId{ get; set; }
    
    // Campus pick list values
    public List<SelectOption> listCampus{
        get{
            if (listCampus == null){
                listCampus = new List<SelectOption>();
                if (opportunityRecordTypeId == null || opportunityRecordTypeId == ''){
                    opportunityRecordTypeId = ((String)this.opportunityRec.RecordTypeId).subString(0, 15);
                }
                if (opportunityRecordTypeId == null || opportunityRecordTypeId == ''){
                    system.debug('====Error: Invalid Opportunity record type id: ' + opportunityRecordTypeId);
                    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Invalid Opportunity record type id: ' + opportunityRecordTypeId));
                    return listCampus;
                }
                //String strCatalogRecordTypeName = mapOpportunityToCatalogRecordType.get(opportunityRecordTypeId);
                String strCatalogRecordTypeName = mapOpportunityToCatalogRecordType.get(mapOpportunityRecordTypes.get(opportunityRecordTypeId));
                if (strCatalogRecordTypeName == null || strCatalogRecordTypeName == ''){
                    system.debug('====Error: Valid Catalog record types not found for opportunity record type id: ' + opportunityRecordTypeId);
                    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Valid Catalog record types not found for opportunity record type id: ' + opportunityRecordTypeId));
                    return listCampus;
                }
                system.debug('====Program Id: ' + strProgramId);
                Map<String, String> mapIds = new Map<String, STring>();
                for (List<Catalog__c> listCatalog : [Select Campus__r.Id, Campus__r.Name, Program__c From Catalog__c 
                                                        //Where Active__c = true AND RecordTypeId = :strCatalogRecordTypeName]){
                                                        Where Active__c = true AND RecordType.DeveloperName = :strCatalogRecordTypeName 
                                                        Order By Campus__r.Name]){
                    for (Catalog__c ct : listCatalog){
                        if (strProgramId != null && strProgramId != ''){
                            if (strProgramId == ct.Program__c){
                                if (mapIds.containsKey(ct.Campus__r.Id) == false){
                                    listCampus.add(new SelectOption(ct.Campus__r.Id, ct.Campus__r.Name));
                                    mapIds.put(ct.Campus__r.Id, '');
                                }
                            }
                        }
                        else{
                            if (mapIds.containsKey(ct.Campus__r.Id) == false){
                                listCampus.add(new SelectOption(ct.Campus__r.Id, ct.Campus__r.Name));
                                mapIds.put(ct.Campus__r.Id, '');
                            }
                        }
                    }
                }
                system.debug('====listCampus size: ' + listCampus.size());
                if (listCampus.size() > 0){
                    listCampus.add(0, new SelectOption('', System.Label.NoneOption));
                }
                else{
                    listCampus.add(new SelectOption('', System.Label.NoneOption));                
                }
            }
            return listCampus;
        }
        set;
    }

    public String PaymentOptions{ get; set; }
    
    public Map<String, String> mapPaymentOptionsValue{
        get{
            if (mapPaymentOptionsValue == null){
                mapPaymentOptionsValue = new Map<String, String>();
                mapPaymentOptionsValue.put(Catalog__c.X3_Payments__c.getDescribe().getLabel(), '3');
                mapPaymentOptionsValue.put(Catalog__c.X4_Payments__c.getDescribe().getLabel(), '4');
                mapPaymentOptionsValue.put(Catalog__c.X5_Payments__c.getDescribe().getLabel(), '5');
                mapPaymentOptionsValue.put(Catalog__c.X6_Payments__c.getDescribe().getLabel(), '6');
                mapPaymentOptionsValue.put(Catalog__c.X10_Payments__c.getDescribe().getLabel(), '10');
                mapPaymentOptionsValue.put(Catalog__c.X11_Payments__c.getDescribe().getLabel(), '11');
                mapPaymentOptionsValue.put(Catalog__c.X12_Payments__c.getDescribe().getLabel(), '12');
                mapPaymentOptionsValue.put(Catalog__c.Early_payoff__c.getDescribe().getLabel(), '1');
            }
            return mapPaymentOptionsValue;
        }
        set;
    }

    public Map<String, String> mapPaymentOptionsLabel{
        get{
            if (mapPaymentOptionsLabel == null){
                mapPaymentOptionsLabel = new Map<String, String>();
                mapPaymentOptionsLabel.put('3', Catalog__c.X3_Payments__c.getDescribe().getLabel());
                mapPaymentOptionsLabel.put('4', Catalog__c.X4_Payments__c.getDescribe().getLabel());
                mapPaymentOptionsLabel.put('5', Catalog__c.X5_Payments__c.getDescribe().getLabel());
                mapPaymentOptionsLabel.put('6', Catalog__c.X6_Payments__c.getDescribe().getLabel());
                mapPaymentOptionsLabel.put('10', Catalog__c.X10_Payments__c.getDescribe().getLabel());
                mapPaymentOptionsLabel.put('11', Catalog__c.X11_Payments__c.getDescribe().getLabel());
                mapPaymentOptionsLabel.put('12', Catalog__c.X12_Payments__c.getDescribe().getLabel());
                mapPaymentOptionsLabel.put('1', Catalog__c.Early_payoff__c.getDescribe().getLabel());
            }
            return mapPaymentOptionsValue;
        }
        set;
    }
    
    public List<SelectOption> listPaymentOptions{
        get{
            if (listPaymentOptions == null){
                listPaymentOptions = new List<SelectOption>();
                //String strCatalogRecordTypeName = mapOpportunityToCatalogRecordType.get(opportunityRecordTypeId);
                String strCatalogRecordTypeName = mapOpportunityToCatalogRecordType.get(mapOpportunityRecordTypes.get(opportunityRecordTypeId));
                system.debug('====Catalog Record Type Name: ' + strCatalogRecordTypeName);
                if (strCatalogRecordTypeName == null || strCatalogRecordTypeName == ''){
                    system.debug('====Error: Valida catagory record types not found for opportunity record type id: ' + opportunityRecordTypeId);
                    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Valid Catalog record types not found for opportunity record type id: ' + opportunityRecordTypeId));
                    return listPaymentOptions;
                }
                List<Schema.PicklistEntry> listPlE = Opportunity.Payment_plan__c.getDescribe().getPicklistValues();
                Map<String, String> mapPaymentPlan = new Map<String, String>();
                for (Schema.PicklistEntry ple : listPlE){
                    mapPaymentPlan.put(ple.getLabel(), ple.getValue());
                }
                system.debug('====CapusId: ' + strCampusId);
                system.debug('====ProgramId: ' + strProgramId);
                if (strCampusId != null && strCampusId != '' && strProgramId != null && strProgramID != ''){
                    List<Catalog__c> listCatalog = [Select X10_payments__c, X11_payments__c, X12_payments__c, X3_payments__c, 
                                                    X4_payments__c, X5_payments__c,X6_payments__c, Early_Payoff__c From Catalog__c Where 
                                                    Active__c = true AND Campus__c = :strCampusId AND Program__c = :strProgramId AND 
                                                    //RecordTypeId = :strCatalogRecordTypeName];
                                                    RecordType.DeveloperName = :strCatalogRecordTypeName];
                    System.debug('====Catalog found in payment options: ' + listCatalog.size());
                    if (listCatalog.size() > 0){
                        if (listCatalog[0].X3_payments__c == true){
                            //listPaymentOptions.add(new SelectOption('3', Catalog__c.X3_Payments__c.getDescribe().getLabel()));
                            listPaymentOptions.add(new SelectOption(mapPaymentOptionsValue.get(Catalog__c.X3_Payments__c.getDescribe().getLabel()), Catalog__c.X3_Payments__c.getDescribe().getLabel()));
                            System.debug('====PaymentOption Found: ' + mapPaymentOptionsValue.get(Catalog__c.X3_Payments__c.getDescribe().getLabel()));
                        }
                        if (listCatalog[0].X4_payments__c == true){
                            //listPaymentOptions.add(new SelectOption('4', Catalog__c.X4_Payments__c.getDescribe().getLabel()));
                            listPaymentOptions.add(new SelectOption(mapPaymentOptionsValue.get(Catalog__c.X4_Payments__c.getDescribe().getLabel()), Catalog__c.X4_Payments__c.getDescribe().getLabel()));
                            System.debug('====PaymentOption Found: ' + mapPaymentOptionsValue.get(Catalog__c.X4_Payments__c.getDescribe().getLabel()));
                        }
                        if (listCatalog[0].X5_payments__c == true){
                            //listPaymentOptions.add(new SelectOption('5', Catalog__c.X5_Payments__c.getDescribe().getLabel()));
                            listPaymentOptions.add(new SelectOption(mapPaymentOptionsValue.get(Catalog__c.X5_Payments__c.getDescribe().getLabel()), Catalog__c.X5_Payments__c.getDescribe().getLabel()));
                            System.debug('====PaymentOption Found: ' + mapPaymentOptionsValue.get(Catalog__c.X5_Payments__c.getDescribe().getLabel()));
                        }
                        if (listCatalog[0].X6_payments__c == true){
                            //listPaymentOptions.add(new SelectOption('6', Catalog__c.X6_Payments__c.getDescribe().getLabel()));
                            listPaymentOptions.add(new SelectOption(mapPaymentOptionsValue.get(Catalog__c.X6_Payments__c.getDescribe().getLabel()), Catalog__c.X6_Payments__c.getDescribe().getLabel()));
                            System.debug('====PaymentOption Found: ' + mapPaymentOptionsValue.get(Catalog__c.X6_Payments__c.getDescribe().getLabel()));
                        }
                        if (listCatalog[0].X10_Payments__c == true){
                            //listPaymentOptions.add(new SelectOption('10', Catalog__c.X10_Payments__c.getDescribe().getLabel()));
                            listPaymentOptions.add(new SelectOption(mapPaymentOptionsValue.get(Catalog__c.X10_Payments__c.getDescribe().getLabel()), Catalog__c.X10_Payments__c.getDescribe().getLabel()));
                            System.debug('====PaymentOption Found: ' + mapPaymentOptionsValue.get(Catalog__c.X10_Payments__c.getDescribe().getLabel()));
                        }
                        if (listCatalog[0].X11_Payments__c == true){
                            //listPaymentOptions.add(new SelectOption('11', Catalog__c.X11_Payments__c.getDescribe().getLabel()));
                            listPaymentOptions.add(new SelectOption(mapPaymentOptionsValue.get(Catalog__c.X11_Payments__c.getDescribe().getLabel()), Catalog__c.X11_Payments__c.getDescribe().getLabel()));
                            System.debug('====PaymentOption Found: ' + mapPaymentOptionsValue.get(Catalog__c.X11_Payments__c.getDescribe().getLabel()));
                        }
                        if (listCatalog[0].X12_Payments__c == true){
                            //listPaymentOptions.add(new SelectOption('12', Catalog__c.X12_Payments__c.getDescribe().getLabel()));
                            listPaymentOptions.add(new SelectOption(mapPaymentOptionsValue.get(Catalog__c.X12_Payments__c.getDescribe().getLabel()), Catalog__c.X12_Payments__c.getDescribe().getLabel()));
                            System.debug('====PaymentOption Found: ' + mapPaymentOptionsValue.get(Catalog__c.X12_Payments__c.getDescribe().getLabel()));
                        }
                        if (listCatalog[0].Early_Payoff__c == true){
                            listPaymentOptions.add(new SelectOption(mapPaymentOptionsValue.get(Catalog__c.Early_Payoff__c.getDescribe().getLabel()), Catalog__c.Early_Payoff__c.getDescribe().getLabel()));
                            System.debug('====PaymentOption Found: ' + mapPaymentOptionsValue.get(Catalog__c.Early_Payoff__c.getDescribe().getLabel()));
                        }
                    }
                }
                if (listPaymentOptions.size() > 0){
                    listPaymentOptions.add(0, new SelectOption('', System.Label.NoneOption));
                }
                else{
                    listPaymentOptions.add(new SelectOption('', System.Label.NoneOption));
                }
            }
            return listPaymentOptions;
        }
        set;
    }
    //Program selected by user
    public String strProgramId{ get; set; }

    // Program pick list values
    public List<SelectOption> listProgram{
        get{
            if (listProgram == null){
                listProgram = new List<SelectOption>();
                if (opportunityRecordTypeId == null || opportunityRecordTypeId == ''){
                    opportunityRecordTypeId = ((String)this.opportunityRec.RecordTypeId).subString(0, 15);
                }
                if (opportunityRecordTypeId == null || opportunityRecordTypeId == ''){
                    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Invalid Opportunity record type id: ' + opportunityRecordTypeId));
                    return listProgram;
                }
                //String strCatalogRecordTypeName = mapOpportunityToCatalogRecordType.get(opportunityRecordTypeId);
                String strCatalogRecordTypeName = mapOpportunityToCatalogRecordType.get(mapOpportunityRecordTypes.get(opportunityRecordTypeId));
                if (strCatalogRecordTypeName == null || strCatalogRecordTypeName == ''){
                    ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Valid Catalog record types not found for opportunity record type id: ' + opportunityRecordTypeId));
                    return listProgram;
                }
                Map<String, String> mapIds = new Map<String,String>();
                for (List<Catalog__c> listCatalog : [Select Program__r.Id, Program__r.Name, Campus__c From Catalog__c 
                                                        Where Active__c = true AND 
                                                        //RecordTypeId = :strCatalogRecordTypeName]){
                                                        RecordType.DeveloperName = :strCatalogRecordTypeName 
                                                        Order By Program__r.Name]){
                    for (Catalog__c ct : listCatalog){
                        if (strCampusID != null && strCampusId != ''){
                            if (strCampusId == ct.Campus__c){
                                if (mapIds.containsKey(ct.Program__r.Id) == false){
                                    listProgram.add(new SelectOption(ct.Program__r.Id, ct.Program__r.Name));
                                    mapIds.put(ct.Program__r.Id, '');
                                }
                            }
                        }
                        else{
                            if (mapIds.containsKey(ct.Program__r.Id) == false){
                                listProgram.add(new SelectOption(ct.Program__r.Id, ct.Program__r.Name));
                                mapIds.put(ct.Program__r.Id, '');
                            }
                        }
                    }
                }
                if (listProgram.size() > 0){
                    listProgram.add(0, new SelectOption('', System.Label.NoneOption));
                }
                else{
                    listProgram.add(0, new SelectOption('', System.Label.NoneOption));
                }
            }
            return listProgram;
        }
        set;
    }
    
    // Change event action for Campus pick list value changed
    public PageReference changeCampus(){
        listProgram = null;
        List<SelectOption> listTemp = listProgram;
        listPaymentOptions = null;
        listTemp = listPaymentOptions;
        return null;
    }
    
    // Change event action for Program pick list value changed
    public PageReference changeProgram(){
        listCampus = null;
        List<SelectOption> listTemp = listCampus;
        listPaymentOptions = null;
        listTemp = listPaymentOptions;
        return null;
    }
    
    // Submit action for Catalog selection
    public PageReference submitChange(){
        bClosePage = false;
        /*if (strCampusId == null || strCampusId == ''){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Please select Campus from the list.'));
            return null;
        }
        if (strProgramId == null || strProgramId == ''){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Please select Campus from the list.'));
            return null;
        }*/
        
        // Set Catalog on Opportunity
        List<Catalog__c> listCatalog = new List<Catalog__c>();
        if (strCampusId != null && strCampusId != '' && strProgramId != null && strProgramId != ''){
            listCatalog = [Select Id From Catalog__c Where 
                                            Campus__c = :strCampusId AND Program__c = :strProgramId AND 
                                            //RecordTypeId = :catalogRecordTypeName and Active__c = true];
                                            RecordType.DeveloperName = :catalogRecordTypeName and Active__c = true];
        }
        /*if (listCatalog.size() <= 0){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'No Catalog found for selected Campus and Program'));
            return null;
        }*/
        bClosePage = true;
        List<Opportunity> listOt = [Select Id, Catalog__c, Payment_Plan__c From Opportunity Where Id = : opportunityRec.Id];
        if (listOt.size() == 1){
            if (listCatalog.size() > 0){
                listOt[0].Catalog__c = listCatalog[0].Id;
            }
            else{
                listOt[0].Catalog__c = null;
            }
            listOt[0].Campus__c = strCampusId;
            listOt[0].Program__c = strProgramId;
            if (paymentOptions == '3'){
                listOt[0].Payment_Plan__c = '3';
            }
            else if (paymentOptions == '4'){
                listOt[0].Payment_plan__c = '4';
            }
            else if (paymentOptions == '5'){
                listOt[0].Payment_plan__c = '5';
            }
            else if (paymentOptions == '6'){
                listOt[0].Payment_plan__c = '6';
            }
            else if (paymentOptions == '10'){
                listOt[0].Payment_plan__c = '10';
            }
            else if (paymentOptions == '11'){
                listOt[0].Payment_plan__c = '11';
            }
            else if (paymentOptions == '12'){
                listOt[0].Payment_plan__c = '12';
            }
            else if (paymentOptions == '1'){
                listOt[0].Payment_plan__c = '1';
            }
            else{
                listOt[0].Payment_plan__c = '';
            }
            //listOt[0].Payment_plan__c = mapPaymentOptionsLabel.get(paymentOptions);
            update listOt;
        }
        //return new PageReference('/' + opportunityRec.Id);
        return null;
    }
    
    
}